package cn.jari.erp.inventory.services;

import cn.jari.erp.inventory.entities.primary.InventoryCategory;
import com.csicit.ace.api.appservice.AppServiceQuery;
import java.time.LocalDateTime;
import cn.jari.erp.inventory.repositories.primary.InventoryCategoryRepository;
import cn.jari.erp.inventory.dto.CreateInventoryCategoryCommand;
import javax.validation.constraints.NotNull;
import cn.jari.erp.inventory.entities.primary.QInventoryCategory;
import cn.jari.erp.inventory.dto.InventoryCategoryReference;
import cn.jari.erp.inventory.dto.UpdateInventoryCategoryCommand;
import cn.jari.erp.inventory.dto.DeleteInventoryCategoryCommand;
import cn.jari.erp.inventory.dto.InventoryCategoryDto;
import com.csicit.ace.api.security.AuthenticationHolder;
import org.springframework.util.StringUtils;
import cn.jari.erp.inventory.convert.ConvertMapper;
import cn.jari.erp.inventory.api.InventoryCategoryService;
import com.csicit.ace.api.audit.AuditServiceApi;
import com.csicit.ace.utils.ApplicationContextUtil;
import com.csicit.ace.utils.TransactionUtils;
import com.csicit.ace.jpaleaf.querydsl.ExpressionConverter;
import com.csicit.ace.api.expr.ExpressionBuilder;
import org.springframework.beans.factory.ObjectProvider;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.OrderSpecifier;
import lombok.NoArgsConstructor;

/*
 * 警告：代码由鲲舟平台生成，请勿手动修改。
 * Warn: This class file is generated by JARI-ACE platform, please do not modify manually。
 */
/**
 * InventoryCategoryService服务实现基类
 */
@NoArgsConstructor
public abstract class AbstractInventoryCategoryServiceImpl implements InventoryCategoryService {
    private final ExpressionBuilder EB = ExpressionBuilder.EXPRESSION_BUILDER;
    private volatile ConvertMapper mapper;
    private volatile AuditServiceApi auditApi;
    private volatile TransactionUtils transUtils;
    private volatile ExpressionConverter exprConverter;
    private volatile JPAQueryFactory jpaQryFact;

    private volatile InventoryCategoryRepository inventoryCategoryRepo;

    protected final ConvertMapper convertMapper() {
        if (mapper == null) {
            synchronized (this) {
                if (mapper == null) {
                    mapper = ApplicationContextUtil.getBean(ConvertMapper.class);
                }
            }
        }
        return mapper;
    }

    protected final AuditServiceApi audit() {
        if (auditApi == null) {
            synchronized (this) {
                if (auditApi == null) {
                    auditApi = ApplicationContextUtil.getBean(AuditServiceApi.class);
                }
            }
        }
        return auditApi;
    }

    protected final TransactionUtils trans() {
        if (transUtils == null) {
            synchronized (this) {
                if (transUtils == null) {
                    transUtils = ApplicationContextUtil.getBean(TransactionUtils.class);
                }
            }
        }
        return transUtils;
    }

    protected final ExpressionConverter expressionConverter() {
        if (exprConverter == null) {
            synchronized (this) {
                if (exprConverter == null) {
                    exprConverter = ApplicationContextUtil.getBean(ExpressionConverter.class);
                }
            }
        }
        return exprConverter;
    }

    protected final JPAQueryFactory jpaQueryFactory() {
        if (jpaQryFact == null) {
            synchronized (this) {
                if (jpaQryFact == null) {
                    jpaQryFact = ApplicationContextUtil.getBean(JPAQueryFactory.class);
                }
            }
        }
        return jpaQryFact;
    }

    protected final InventoryCategoryRepository inventoryCategoryRepository() {
        if (inventoryCategoryRepo == null) {
            synchronized (this) {
                if (inventoryCategoryRepo == null) {
                    inventoryCategoryRepo = ApplicationContextUtil.getBean(InventoryCategoryRepository.class);
                }
            }
        }
        return inventoryCategoryRepo;
    }

    @Override
    public InventoryCategoryReference getByName(String name) {
        return inventoryCategoryRepository().getByName(name);
    }

    protected Predicate modifyPredicateForGetByName(String name, Predicate pred, QInventoryCategory root) {
        return pred;
    }

    protected OrderSpecifier<?>[] modifyOrderByForGetByName(String name, QInventoryCategory root) {
        return new OrderSpecifier<?>[0];
    }

    @Override
    public InventoryCategoryDto createInventoryCategory(CreateInventoryCategoryCommand command) {
        final var logonUser = AuthenticationHolder.getAuthentication().getAuthenticatedUser();
        if (!StringUtils.hasText(command.getReleaseSource())) {
            final var installInfo = ApplicationContextUtil.getBean(AppServiceQuery.class).getInstallInfo();
            command.setReleaseSource(installInfo.getId());
        }
        return trans().required(()-> {
            final var entity = convertMapper().map(command);
            entity.setCreatedByUser(logonUser.getId());
            final var dept = logonUser.getDepartment();
            entity.setCreatedByDept(dept == null ? null : dept.getId());
            entity.setCreatedByUserName(logonUser.getFullName());
            entity.setCreatedByDeptName(dept==null? null: dept.getName());
            entity.setCreatedByRealmName(logonUser.getRealmName());
            entity.setCreatedTime(LocalDateTime.now());
            entity.setReleaseSource(command.getReleaseSource());
            doBeforeCreateInventoryCategory(entity, command);
            inventoryCategoryRepository().save(entity);
            doAfterCreateInventoryCategory(entity, command);
            return convertMapper().mapToInventoryCategoryDto(entity);
        });
    }

    protected void doAfterCreateInventoryCategory(InventoryCategory entity, CreateInventoryCategoryCommand command) {
    }

    protected void doBeforeCreateInventoryCategory(InventoryCategory entity, CreateInventoryCategoryCommand command) {
    }

    @Override
    public InventoryCategoryDto updateInventoryCategory(UpdateInventoryCategoryCommand command) {
        return trans().required(()-> {
            var entity = convertMapper().map(command);
            doBeforeUpdateInventoryCategory(entity, command);
            inventoryCategoryRepository().save(entity);
            doAfterUpdateInventoryCategory(entity, command);
            return convertMapper().mapToInventoryCategoryDto(entity);
        });
    }

    protected void doAfterUpdateInventoryCategory(InventoryCategory entity, UpdateInventoryCategoryCommand command) {
    }

    protected void doBeforeUpdateInventoryCategory(InventoryCategory entity, UpdateInventoryCategoryCommand command) {
    }

    @Override
    public InventoryCategoryDto deleteInventoryCategory(DeleteInventoryCategoryCommand command) {
        return trans().required(()-> {
            var entity = convertMapper().map(command);
            doBeforeDeleteInventoryCategory(entity, command);
            inventoryCategoryRepository().delete(entity);
            doAfterDeleteInventoryCategory(entity, command);
            return convertMapper().mapToInventoryCategoryDto(entity);
        });
    }

    protected void doAfterDeleteInventoryCategory(InventoryCategory entity, DeleteInventoryCategoryCommand command) {
    }

    protected void doBeforeDeleteInventoryCategory(InventoryCategory entity, DeleteInventoryCategoryCommand command) {
    }
}
